package com.mini.mybatis.session;

import com.mini.mybatis.binding.MapperRegistry;
import com.mini.mybatis.mapping.MappedStatement;
import com.mini.mybatis.reflection.MetaObject;
import com.mini.mybatis.reflection.factory.DefaultObjectFactory;
import com.mini.mybatis.reflection.factory.ObjectFactory;
import com.mini.mybatis.type.TypeHandlerRegistry;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 配置类 - MyBatis的核心配置信息
 * 包含数据源、映射器注册表、SQL映射语句等
 */
public class Configuration {
    
    /**
     * 数据源配置
     */
    protected DataSource dataSource;
    
    /**
     * 映射器注册表 - 管理所有的Mapper接口
     */
    protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
    
    /**
     * 映射的语句 - 存储所有的SQL语句配置
     * key: statementId (namespace.id)
     * value: MappedStatement对象
     */
    protected final Map<String, MappedStatement> mappedStatements = new HashMap<>();
    
    /**
     * 对象工厂 - 用于创建对象实例
     */
    protected ObjectFactory objectFactory = new DefaultObjectFactory();
    
    /**
     * 类型处理器注册表 - 管理Java类型和JDBC类型的转换
     */
    protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
    
    /**
     * 已加载的资源集合 - 防止重复加载
     */
    protected final Set<String> loadedResources = new HashSet<>();
    
    /**
     * 获取数据源
     */
    public DataSource getDataSource() {
        return dataSource;
    }
    
    /**
     * 设置数据源
     */
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    /**
     * 获取映射器注册表
     */
    public MapperRegistry getMapperRegistry() {
        return mapperRegistry;
    }
    
    /**
     * 添加映射器
     */
    public <T> void addMapper(Class<T> type) {
        mapperRegistry.addMapper(type);
    }
    
    /**
     * 获取映射器
     */
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
    }
    
    /**
     * 是否包含映射器
     */
    public boolean hasMapper(Class<?> type) {
        return mapperRegistry.hasMapper(type);
    }
    
    /**
     * 添加映射语句
     */
    public void addMappedStatement(MappedStatement ms) {
        mappedStatements.put(ms.getId(), ms);
    }
    
    /**
     * 获取映射语句
     */
    public MappedStatement getMappedStatement(String id) {
        return mappedStatements.get(id);
    }
    
    /**
     * 获取所有映射语句
     */
    public Map<String, MappedStatement> getMappedStatements() {
        return mappedStatements;
    }
    
    /**
     * 获取对象工厂
     */
    public ObjectFactory getObjectFactory() {
        return objectFactory;
    }
    
    /**
     * 设置对象工厂
     */
    public void setObjectFactory(ObjectFactory objectFactory) {
        this.objectFactory = objectFactory;
    }
    
    /**
     * 检查资源是否已加载
     */
    public boolean isResourceLoaded(String resource) {
        return loadedResources.contains(resource);
    }
    
    /**
     * 添加已加载的资源
     */
    public void addLoadedResource(String resource) {
        loadedResources.add(resource);
    }
    
    /**
     * 获取类型处理器注册表
     */
    public TypeHandlerRegistry getTypeHandlerRegistry() {
        return typeHandlerRegistry;
    }
    
    /**
     * 创建MetaObject
     * @param object 目标对象
     * @return MetaObject实例
     */
    public MetaObject newMetaObject(Object object) {
        return MetaObject.forObject(object);
    }
}